/*
 * Pref.m
 * Copyright 2008 . All rights reserved.
 */

#import "Pref.h"

static sqlite3_stmt *get_statement = nil;
static sqlite3_stmt *delete_statement = nil;
static sqlite3_stmt *save_statement = nil;

@interface Pref (Private)
+ (NSString *) _getFormatString:(int)digits;
+ (NSString *) _getDistanceText:(UnitType)ut;
+ (NSString *) _getFuelText:(UnitType)ut;
+ (NSString *) _getDpfText:(UnitType)ut;
+ (NSString *) _getCpdText:(UnitType)ut;
@end

#pragma mark -
@implementation Pref

@synthesize database, odometerDigits, volumeDigits, costDigits, units;
@synthesize dirty;
@synthesize dateFormatter, distanceFormatter, volumeFormatter, costFormatter, unitCostFormatter ,consumptionFormatter;
// @synthesize distanceText; // fuelText; //, dpfText, cpdText;

+ (NSString *) _getFormatString:(int) digits {
	switch (digits) {
		case 1: return DECIMAL_1;
		case 2: return DECIMAL_2;
		case 3: return DECIMAL_3;
		default: return DECIMAL_0;
	}
}

+ (NSString *) _getDistanceText:(UnitType) ut {
	switch (ut) {
		case ENGLISH: return MILES;
		case UK: return MILES;
		case METRIC: return KILOMETRES;
		case INV_METRIC: return KILOMETRES;
		case NORWAY: return KILOMETRES;
		default: return DISTANCE;
	}
}

+ (NSString *) _getFuelText:(UnitType) ut {
	switch (ut) {
		case ENGLISH: return GALLONS;
		case UK: return LITRES;
		case METRIC: return LITRES;
		case INV_METRIC: return LITRES;
		case NORWAY: return LITRES;
		default: return VOLUME;
	}
}

+ (NSString *) _getDpfText:(UnitType) ut {
	switch (ut) {
		case ENGLISH: return MPG;
		case UK: return MPG;
		case METRIC: return KMPL;
		case INV_METRIC: return LPKM;
		case NORWAY: return LPKM_NORWAY;
		default: return DPF;
	}
}

+ (NSString *) _getCpdText:(UnitType) ut {
	switch (ut) {
		case ENGLISH: return CPM;
		case UK: return CPM;
		case METRIC: return CPKM;
		case INV_METRIC: return CPKM;
		case NORWAY: return CPKM;
		default: return CPD;
	}
}

#pragma mark -
#pragma mark distanceText

- (NSArray *)distanceTextShortArray {
	return	[[[NSArray alloc] initWithObjects:
			  [NSString stringWithString:(NSLocalizedString(@"PrefsdistanceTextShort Miles",@"Miles"))],
			  [NSString stringWithString: (NSLocalizedString(@"PrefsdistanceTextShort Kilometer",@"Kilometer"))],
			  [NSString stringWithString:(NSLocalizedString(@"PrefsdistanceTextShort Distance",@"Dist. / fuel"))], 	 
			  [NSString stringWithString: (NSLocalizedString(@"PrefsdistanceTextShort Kilometer",@"Kilometer"))],
			  [NSString stringWithString:(NSLocalizedString(@"PrefsdistanceTextShort Miles",@"Miles"))],
			  [NSString stringWithString: (NSLocalizedString(@"PrefsdistanceTextShort Kilometer",@"Kilometer"))],
			  nil] autorelease] ;
	/*
	 ENGLISH,     // mpg
	 METRIC,      // km/L
	 GENERIC,    
	 INV_METRIC,  // L/100km
	 UK,          // mpg
	 NORWAY       // L/10km
	 */
	
}

- (void)distanceTextShortArray:(NSArray *)value {
	
}

- (NSString *)distanceText {
	NSString * returnValue =  [[self distanceTextShortArray] objectAtIndex:self.units];
 	return returnValue;
	
}

- (void)setDistanceText:(NSString *)value {
}

#pragma mark - 
#pragma mark fuelText
- (NSArray *)fuelTextShortArray {
  	return	[[[NSArray alloc] initWithObjects:
			  [NSString stringWithString:(NSLocalizedString(@"PrefsfuelTextShort Gallons US",@"Gallons US"))],
			  [NSString stringWithString: (NSLocalizedString(@"PrefsfuelTextShort Litres",@"Litres"))],
			  [NSString stringWithString:(NSLocalizedString(@"PrefsfuelTextShort Fuel",@"Fuel"))], 	 
			  [NSString stringWithString: (NSLocalizedString(@"PrefsfuelTextShort Litres",@"Litres"))],
			  [NSString stringWithString:(NSLocalizedString(@"PrefsfuelTextShort Gallons UK",@"Gallons UK"))],
			  [NSString stringWithString: (NSLocalizedString(@"PrefsfuelTextShort Litres",@"Litres"))],
			  nil] autorelease] ;
	/*
	 ENGLISH,     // mpg
	 METRIC,      // km/L
	 GENERIC,    
	 INV_METRIC,  // L/100km
	 UK,          // mpg
	 NORWAY       // L/10km
	 
	 */
	
}

- (void)setFuelTextShortArray:(NSArray *)value {
	
}


- (NSString *)fuelText {
 	NSString * returnValue =  [[self fuelTextShortArray] objectAtIndex:self.units];
 	return returnValue;
}

- (void)setFuelText:(NSString *)value {
 }


- (double)fuelConversionFactor {
	double returnValue = 0.0;
	UnitType dummy = self.units;
	switch (dummy) {
		case ENGLISH:	// mpg US
			returnValue = 3.785411784;
			break;
		case METRIC:       // km/L
		case GENERIC:    
		case INV_METRIC:  // L/100km
		case NORWAY :      // L/10km
		default:
			returnValue = 1.0;
			break;
		case UK:          // mpg
			returnValue = 4.54609;
			break;	 
	}
 	
    return returnValue;
}

- (void)setFuelConversionFactor:(double)value {
	
}



#pragma mark -
#pragma mark dpfText

- (NSArray *)dpfTextShortArray {
	return	[[[NSArray alloc] initWithObjects:
			  [NSString stringWithString:(NSLocalizedString(@"PrefsdpfTextShort mpg",@"mpg"))],
			  [NSString stringWithString: (NSLocalizedString(@"PrefsdpfTextShort km/L",@"km/L"))],
			  [NSString stringWithString:(NSLocalizedString(@"PrefsdpfTextShort Dist. / fuel",@"Dist. / fuel"))], 	 
			  [NSString stringWithString:(NSLocalizedString(@"PrefsdpfTextShort L/100km",@"L/100km"))],
			  [NSString stringWithString:(NSLocalizedString(@"PrefsdpfTextShort mpg",@"mpg"))],
			  [NSString stringWithString:(NSLocalizedString( @"PrefsdpfTextShort L/10km", @"L/10km"))],
			  nil] autorelease] ;
	/*
	 ENGLISH,     // mpg
	 METRIC,      // km/L
	 GENERIC,    
	 INV_METRIC,  // L/100km
	 UK,          // mpg
	 NORWAY       // L/10km
	 */
	
}

- (void)setDpfTextShortArray:(NSArray *)value {
	
}

- (NSString *)dpfText {
	NSString * returnValue =  [[self dpfTextShortArray] objectAtIndex:self.units];
 	return returnValue;
	
}

- (void)setDpfText:(NSString *)value {
}




- (NSArray *)dpfTextLongArray {
	
	return	[[[NSArray alloc] initWithObjects:
			  [NSString stringWithString:(NSLocalizedString(@"PrefsdpfLongShort Miles per Gallon US",@"Miles per Gallon US"))],
			  [NSString stringWithString:(NSLocalizedString(@"PrefsdpfLongShort Kilometer per Liter",@"Kilometer per Liter")) ],
			  [NSString stringWithString:(NSLocalizedString(@"PrefsdpfLongShort Dist. / fuel",@"Dist. / fuel"))], 	 
			  [NSString stringWithString:(NSLocalizedString(@"PrefsdpfLongShort Liter per 100km",@"Liter per 100km"))],
			  [NSString stringWithString:(NSLocalizedString(@"PrefsdpfLongShort Miles per Gallon UK",@"Miles per Gallon UK"))],
			  [NSString stringWithString:(NSLocalizedString( @"PrefsdpfLongShort Liter per 10km", @"Liter per 10km"))],
			  nil] autorelease] ;
	/*
	 ENGLISH,     // mpg
	 METRIC,      // km/L
	 GENERIC,    
	 INV_METRIC,  // L/100km
	 UK,          // mpg
	 NORWAY       // L/10km
	 */
	
}

- (void)setDpfTextLongArray:(NSArray *)value {
	
}




- (NSString *)dpfTextLong {
	NSString * returnValue =  [[self dpfTextLongArray] objectAtIndex:self.units];
 	return returnValue;
	
}

- (void)setDpfTextLong:(NSString *)value {
	
}

#pragma mark -
#pragma mark cpdText

- (NSArray *)cpdTextShortArray {
	return	[[[NSArray alloc] initWithObjects:
			  [NSString stringWithString:(NSLocalizedString(@"PrefscpdTextShort Cost per mile", @"Cost per mile"))],
			  [NSString stringWithString:(NSLocalizedString(@"PrefscpdTextShort Cost per km",@"Cost per km"))],
			  [NSString stringWithString:(NSLocalizedString(@"PrefscpdTextShort Dist. / fuel",@"Dist. / fuel"))], 	 
			  [NSString stringWithString:(NSLocalizedString(@"PrefscpdTextShort Cost per km",@"Cost per km"))],
			  [NSString stringWithString:(NSLocalizedString(@"PrefscpdTextShort Cost per mile", @"Cost per mile"))],
			  [NSString stringWithString:(NSLocalizedString(@"PrefscpdTextShort Cost per km",@"Cost per km"))],
			  nil] autorelease] ;
	/*
	 ENGLISH,     // 0 mpg
	 METRIC,      // 1 km/L
	 GENERIC,    //  2
	 INV_METRIC,  // 3 L/100km
	 UK,          // 4 mpg
	 NORWAY       // 5 L/10km
	 */
}


- (NSString *)cpdText {
	NSString * returnValue =  [[self cpdTextShortArray] objectAtIndex:self.units];
 	return returnValue;
	
}


- (void)setCpdText:(NSString *)value {
    if (cpdText != value) {
        [cpdText release];
        cpdText = [value copy];
    }
}

//*/

- (int)units {
    return units;
}

- (void)setUnits:(int)value {
    if (units != value) {
        units = value;
    }
}



#pragma mark -


// Finalize statements
+ (void)finalizeStatements {
	if (get_statement) sqlite3_finalize(get_statement);
	if (delete_statement) sqlite3_finalize(delete_statement);
	if (save_statement) sqlite3_finalize(save_statement);
	get_statement = nil;
	delete_statement = nil;
	save_statement = nil;
}

+ (Pref *)getAll:(sqlite3 *)db {
	if (get_statement == nil) {
		const char *sql = "SELECT key,digits FROM prefs";
		if (sqlite3_prepare_v2(db, sql, -1, &get_statement, NULL) != SQLITE_OK) {
			NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(db));
		}
	}
	Pref *pref = [Pref alloc];
	[pref setOdometerDigits:0];
	[pref setVolumeDigits:3];
	[pref setCostDigits:2];
	[pref setUnits:GENERIC];
	while (sqlite3_step(get_statement) == SQLITE_ROW) {
		int key = sqlite3_column_int(get_statement, 0);
		int digits = sqlite3_column_int(get_statement, 1);
		switch (key) {
			case FUELLOG_ODOMETER:
				[pref setOdometerDigits:digits];
				break;
			case FUELLOG_VOLUME:
				[pref setVolumeDigits:digits];
				break;
			case FUELLOG_COST:
				[pref setCostDigits:digits];
				break;
			case FUELLOG_UNITS:
				[pref setUnits:digits];
		}
	}
	[pref setDirty:NO];
	[pref setDatabase:db];
	sqlite3_reset(get_statement);	
	
	pref.dateFormatter = [[NSDateFormatter alloc] init];
	[pref.dateFormatter setDateStyle:NSDateFormatterMediumStyle];
	[pref.dateFormatter setTimeStyle:NSDateFormatterNoStyle];
	
	pref.distanceFormatter = [[NSNumberFormatter alloc] init];
	[pref.distanceFormatter setPositiveFormat:[Pref _getFormatString:pref.odometerDigits]];
	
	pref.volumeFormatter = [[NSNumberFormatter alloc] init];
	[pref.volumeFormatter setPositiveFormat:[Pref _getFormatString:pref.volumeDigits]];
	
	pref.costFormatter = [[NSNumberFormatter alloc] init];
	[pref.costFormatter setPositiveFormat:[Pref _getFormatString:pref.costDigits]];
	
	pref.unitCostFormatter = [[NSNumberFormatter alloc] init];
	[pref.unitCostFormatter setPositiveFormat:[Pref _getFormatString:3]];
	
	pref.consumptionFormatter = [[NSNumberFormatter alloc] init];
	switch (pref.units) {
		case ENGLISH:
		case UK:
			[pref.consumptionFormatter setPositiveFormat:[Pref _getFormatString:1]];
			break;
		default:
			[pref.consumptionFormatter setPositiveFormat:[Pref _getFormatString:2]];
			break;
	}
	
	pref.distanceText = [Pref _getDistanceText:pref.units];
	pref.fuelText = [Pref _getFuelText:pref.units];
	pref.dpfText = [Pref _getDpfText:pref.units];
	pref.cpdText = [Pref _getCpdText:pref.units];
	
	return pref;
}

- (void)saveAll {
	if (!dirty) {
		return;
	}
	
	// delete all then re-insert all

	if (delete_statement == nil) {
		const char *sql = "DELETE FROM prefs";
		if (sqlite3_prepare_v2(database, sql, -1, &delete_statement, NULL) != SQLITE_OK) {
			NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
		}
	}
	int success = sqlite3_step(delete_statement);
	sqlite3_reset(delete_statement);
	if (success != SQLITE_DONE) {
		NSAssert1(0, @"Error: failed to delete with message '%s'.", sqlite3_errmsg(database));
	}
	
	if (save_statement == nil) {
		const char *sql = "INSERT INTO prefs (key,digits) values (?,?)";
		if (sqlite3_prepare_v2(database, sql, -1, &save_statement, NULL) != SQLITE_OK) {
			NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
		}
	}

	sqlite3_bind_int(save_statement, 1, FUELLOG_ODOMETER);
	sqlite3_bind_int(save_statement, 2, odometerDigits);
	success = sqlite3_step(save_statement);
	sqlite3_reset(save_statement);
	if (success != SQLITE_DONE) {
		NSAssert1(0, @"Error: failed to save with message '%s'.", sqlite3_errmsg(database));
	}
	[distanceFormatter setPositiveFormat:[Pref _getFormatString:odometerDigits]];

	sqlite3_bind_int(save_statement, 1, FUELLOG_VOLUME);
	sqlite3_bind_int(save_statement, 2, volumeDigits);
	success = sqlite3_step(save_statement);
	sqlite3_reset(save_statement);
	if (success != SQLITE_DONE) {
		NSAssert1(0, @"Error: failed to save with message '%s'.", sqlite3_errmsg(database));
	}
	[volumeFormatter setPositiveFormat:[Pref _getFormatString:volumeDigits]];
	
	sqlite3_bind_int(save_statement, 1, FUELLOG_COST);
	sqlite3_bind_int(save_statement, 2, costDigits);
	success = sqlite3_step(save_statement);
	sqlite3_reset(save_statement);
	if (success != SQLITE_DONE) {
		NSAssert1(0, @"Error: failed to save with message '%s'.", sqlite3_errmsg(database));
	}
	[costFormatter setPositiveFormat:[Pref _getFormatString:costDigits]];

	sqlite3_bind_int(save_statement, 1, FUELLOG_UNITS);
	sqlite3_bind_int(save_statement, 2, units);
	success = sqlite3_step(save_statement);
	sqlite3_reset(save_statement);
	if (success != SQLITE_DONE) {
		NSAssert1(0, @"Error: failed to save with message '%s'.", sqlite3_errmsg(database));
	}
	distanceText = [Pref _getDistanceText:units];
	fuelText = [Pref _getFuelText:units];
	dpfText = [Pref _getDpfText:units];
	cpdText = [Pref _getCpdText:units];
	
	dirty = NO;
}

- (void) setPrefs:(int)newOdometerDigits volumeDigits:(int)newVolumeDigits costDigits:(int)newCostDigits units:(int)newUnits {
	if (newOdometerDigits >= 0 && newOdometerDigits != odometerDigits) {
		odometerDigits = newOdometerDigits;
		dirty = YES;
	}
	if (newVolumeDigits >= 0 && newVolumeDigits != volumeDigits) {
		volumeDigits = newVolumeDigits;
		dirty = YES;
	}
	if (newCostDigits >= 0 && newCostDigits != costDigits) {
		costDigits = newCostDigits;
		dirty = YES;
	}
	if (newUnits >= 0 && newUnits != units) {
		units = newUnits;
		dirty = YES;
	}
	if (dirty) {
		[self saveAll];
	}
}

@end
